package com.jargonee.activities;

import java.util.Arrays;
import java.util.Hashtable;

import org.json.JSONException;
import org.json.JSONObject;

import com.jargonee.threads.BackendThread;
import com.jargonee.threads.BackendThread.BackendThreadMessages;
import com.jargonee.threads.BackendThread.BackendThreadModes;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings.System;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;

public class JargoneeInput extends Activity {

	// different types of dialogs
	static final int PROGRESS_DIALOG = 0;
	static final int WORD_TYPE_DIALOG = 1;
	static final int MESSAGE_DIALOG = 2;
	static final int SUBMISSION_SUCCESS_DIALOG = 3;
	
	// view components
	private EditText wordText;
	private EditText definitionText;
	private EditText usageText;
	private Button submitButton;
	private Button cancelButton;
	private Spinner speechSpinner;
	private Spinner categorySpinner;
	private InputMethodManager softKeyboard;
	private LocationManager locationManager;
	
	// Define the Handler that receives messages from the search thread and update the progress
    final Handler handler = new Handler() { public void handleMessage(Message msg) { handleJargoneeInputMessage(msg);}};
	
	/**
	 * Called when the activity is first created
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.jargonee_input);
		
		
		// get view component references
		wordText = (EditText) findViewById(R.id.WordEditText);
		definitionText = (EditText) findViewById(R.id.DefinitionEditText);
		usageText = (EditText) findViewById(R.id.UsageEditText);
		categorySpinner = (Spinner) findViewById(R.id.CategorySpinner);
		speechSpinner = (Spinner) findViewById(R.id.PartOfSpeechSpinner);
		submitButton = (Button) findViewById(R.id.SubmitButton);
		cancelButton = (Button) findViewById(R.id.CancelButton);
		
		// get word, address, and radius
		Bundle extras = getIntent().getExtras();
	    if (extras != null) {
	    	String word = extras.getString("word");
	    	if(word != null && word.length() > 0) {
	    		wordText.setText(word);
				wordText.setTextColor(Color.BLACK);
	    	}
	    }
		
		// get system services
		softKeyboard = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		
		// word box key listener
		wordText.setOnKeyListener(new OnKeyListener() {
			public boolean onKey(View v, int keyCode, KeyEvent event) {

				// When Enter is pressed hide softkeyboard and lose focus
				if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
					softKeyboard.hideSoftInputFromWindow(v.getWindowToken(), 0);
					//visibleTypeTextView.requestFocus();
					return true;
				}
				return false;
			}
		});
		
		// word box change listener
		wordText.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {

				// if gets focus and default search string is there remove it and set text to black
				if (hasFocus && ((EditText) v).getText().toString().
						equalsIgnoreCase(getResources().getString(R.string.seach_default))) {
					wordText.setText("", TextView.BufferType.EDITABLE);
					wordText.setTextColor(Color.BLACK);
				}
			}
		});
		
		// definition box change listener
		definitionText.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {

				// if gets focus and default search string is there remove it and set text to black
				if (hasFocus && ((EditText) v).getText().toString().
						equalsIgnoreCase(getResources().getString(R.string.definition_default))) {
					definitionText.setText("", TextView.BufferType.EDITABLE);
					definitionText.setTextColor(Color.BLACK);
				}
			}
		});
		
		usageText.setOnFocusChangeListener(new OnFocusChangeListener() {
			public void onFocusChange(View v, boolean hasFocus) {

				// if gets focus and default search string is there remove it and set text to black
				if (hasFocus && ((EditText) v).getText().toString().
						equalsIgnoreCase(getResources().getString(R.string.definition_default))) {
					usageText.setText("", TextView.BufferType.EDITABLE);
					usageText.setTextColor(Color.BLACK);
				}
			}
		});
		
		// submit word when search button is clicked
		submitButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if(isValidInput()) {
					Bundle bundle = new Bundle();
					bundle.putString("display message", "Getting current address. Please wait...");
					showDialog(PROGRESS_DIALOG, bundle);
					getLocation();
				}
			}
		});
		
		// finish when cancel button is clicked
		cancelButton.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.putExtra("submitted", false);
				setResult(200, intent);
				finish();
			}
		});
	}
	
	/**
	 * Creates dialogs
	 */
	@Override
	protected Dialog onCreateDialog(int id, Bundle args) {
		Dialog dialog = null;
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		switch(id) {
			case PROGRESS_DIALOG:
				dialog = ProgressDialog.show(this, "", args.getString("display message"), true);
				break;
			case MESSAGE_DIALOG:
				// build alert dialog with error message and ok button
				builder.setMessage(args.getString("message"))
			       .setCancelable(false)
			       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			        	   removeDialog(MESSAGE_DIALOG);
			           }
			       });
				dialog = builder.create();
				break;
			case SUBMISSION_SUCCESS_DIALOG:
				builder.setMessage("You have successfully submitted a definition")
				.setCancelable(false)
				.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
			           public void onClick(DialogInterface dialog, int id) {
			        	   Intent intent = new Intent();
			        	   intent.putExtra("submitted", true);
			        	   setResult(200, intent);
			        	   finish();
			           }
			       });
		}
		return dialog;
	}
	
	private void adjustSubmitButton() {
		if(wordText.getText().toString().equalsIgnoreCase(getResources().getString(R.string.word_default)) || 
				definitionText.getText().toString().equalsIgnoreCase(getResources().getString(R.string.definition_default)))
			submitButton.setVisibility(View.INVISIBLE);
		else
			submitButton.setVisibility(View.VISIBLE);
	}
	
	private boolean isValidInput() {
		if(wordText.getText().length() < 1 || wordText.getTextColors().getDefaultColor() == Color.LTGRAY) {
			Bundle bundle = new Bundle();
			bundle.putString("message", "You must enter a term to define.");
			showDialog(MESSAGE_DIALOG, bundle);
			return false;
		}
		if(definitionText.getText().length() < 1 || definitionText.getTextColors().getDefaultColor() == Color.LTGRAY) {
			Bundle bundle = new Bundle();
			bundle.putString("message", "You must enter definition to define term.");
			showDialog(MESSAGE_DIALOG, bundle);
			return false;
		}
		
		return true;
	}
	
	private void submitDefinition(Address address) {
		
		String udid = System.getString(getContentResolver(), System.ANDROID_ID);
		String word = wordText.getText().toString();
		String area = address.getSubAdminArea() +","+ address.getAdminArea() +","+ address.getCountryName();
		String definition = definitionText.getText().toString();
		String category = (String)categorySpinner.getSelectedItem();
		String partOfSpeech = (String)speechSpinner.getSelectedItem();
		String usage = usageText.getText().toString();
		Double latitude = address.getLatitude();
		Double longitude = address.getLatitude();
		
		JSONObject buzzword = new JSONObject();
		try {
			buzzword.put("udid", udid);
			buzzword.put("word", word);
			buzzword.put("area", area);
			buzzword.put("definition", definition);
			buzzword.put("category", category);
			buzzword.put("partOfSpeech", partOfSpeech);
			buzzword.put("usage", usage);
			buzzword.put("latitude", latitude);
			buzzword.put("longitude", longitude);
		} catch (JSONException je) {
			// do someting
		}
		
		Hashtable<String,Object> extraParams = new Hashtable<String, Object>();
		Uri.Builder uriBuilder = new Uri.Builder();
		uriBuilder = uriBuilder.encodedPath(getResources().getString(R.string.jargonee_host) + "service/buzzword/post/");
		extraParams.put("uriBuilder", uriBuilder);
		extraParams.put("json", buzzword.toString());
		
		// kickoff thread
		BackendThread thread = new BackendThread(handler, BackendThreadModes.SubmitDefinition, extraParams);
		thread.start();
	}
	
	/**
	 * Handle message return from threads
	 * @param msg Message returned from thread
	 */
	private void handleJargoneeInputMessage(Message msg) {
		dismissDialog(PROGRESS_DIALOG);
		switch((BackendThreadMessages)msg.getData().getSerializable("message type")) {
			case SubmitSuccessful:
				break;
			case TroubleSubmittingDefinition:
				break;
			case TroubleGettingLocation:
    			showDialog(MESSAGE_DIALOG, msg.getData());
    			break;
			case LocationFound:
    			submitDefinition((Address)msg.obj);
    			break;
			default:
				break;
		}
	}
	
	/**
	 * Start buzzwords search in a separate thread
	 */
	private void getLocation() {
		
		// package extra parameters needed
		Geocoder geocoder = new Geocoder(this);
		Hashtable<String,Object> extraParams = new Hashtable<String, Object>();
		extraParams.put("locationManager", locationManager);
		extraParams.put("geocoder", geocoder);
		
		// kickoff thread
		BackendThread thread = new BackendThread(handler, BackendThreadModes.RetrieveCurrentAddress, extraParams);
		thread.start();
	}
	
	
}
